package cn.abellflower.model;

/**
 * @Description
 * @Author gbzdyf@126.com
 * @Date 2020/10/25 11:49 下午
 */
public class SingletonDesignModule {

    /**
     * volatile 只能保证内存可见行 不能真正意义上的同步
     * 与 JAVA 内存模型有关 用户内存（数据的一份拷贝） -> 主内存
     * 当两个修改了用户内存中的值 还没有刷新到 主内存，同时另一个线程去获取则得到的是旧值
     * volatile : 禁止指令重排
     */
    private volatile static SingletonDesignModule singletonDesignModule;


    /**
     *
     */
    private static SingletonDesignModule singletonDesignModuleUn;

    /**
     * 同步锁（会有性能开销，因只需要初始化一次的时候用到，之后的调用没必要加锁）
     * @return
     */
    public synchronized SingletonDesignModule getInstanceBySynchronized() {
        if (null == singletonDesignModuleUn) {
            singletonDesignModuleUn = new SingletonDesignModule();
        }
        return singletonDesignModuleUn;
    }

    /**
     * 错误的双重检测
     * 1、检查变量是否初始化（不获取锁）如果初始化成功则获取对象
     * 2、获取锁
     * 3、再次检查是否已经初始化,如果没有初始化就初始化一个对象
     * @return
     */
    public static SingletonDesignModule getInstanceByDoubleCheckLockInstanceError() {
        if (null == singletonDesignModuleUn) {
            synchronized (SingletonDesignModule.class) {
                //error (1、分配内存空间 2、初始化对象 3、将对象指向刚分配的内存空间)
                //指令重排（1 - 3 - 2）
                // ThreadA                                          ThreadB
                // 检查doubleCheckedLockingModuleUn为空
                // 获取锁
                // 再次检查doubleCheckedLockingModuleUn为空
                // 分配内存空间
                // 将doubleCheckedLockingModuleUn指向刚分配的内存空间
                //                                                  检查到doubleCheckedLockingModuleUn不为空
                //                                                  访问（此时对象未完成初始化）
                //初始化
                singletonDesignModuleUn = new SingletonDesignModule();
            }
        }
        return singletonDesignModuleUn;
    }

    /**
     * 双重锁检测
     * @return
     */
    public static SingletonDesignModule getInstanceByDoubleCheckLockInstance() {
        if (null == singletonDesignModule) {
            synchronized (SingletonDesignModule.class) {
                singletonDesignModule = new SingletonDesignModule();
            }
        }
        return singletonDesignModule;
    }

    /**
     * 内部类方式单利
     */
    private static class Inner {
        public static SingletonDesignModule innerSingletonModule = new SingletonDesignModule();
    }

    /**
     * 获取内部类单例模式
     * @return
     */
    public SingletonDesignModule getInstanceByInnerModule() {
        return Inner.innerSingletonModule;
    }
}
